/******************************************************************************************
 * Import
 ******************************************************************************************/

// module
import _ from 'lodash';
import io from 'weapp.socket.io';

/******************************************************************************************
 * Export Class
 ******************************************************************************************/

/**
 * Socket设置对象结构：
 * {
 *      url: string,                    // socket服务器的url地址,
 *      event: [                        // 需要注册到socket对象上的事件数组（不接受系统事件）
 *          {key: callback(data) {}},
 *          {key: callback(data) {}}
 *      ],
 *      config: {                       // 设置对象
 *          debug: boolean,             // 是否打开debug
 *          indicator: {                // 指示器（吐司菜单）对象（发送http请求时显示，完成http请求时隐藏）
 *              start() {},             // 开始执行动作回调
 *              end() {}                // 结束执行动作回调
 *          },
 *          fail: {                     // 失败对象，对服务端错误、网络错误的统一处理
 *              status(res, obj) {},    // 服务器状态错误处理器
 *              parse(text, obj) {},    // 返回值解析错误处理器
 *              format(text, obj) {},   // 返回值的格式错误处理器
 *              network(err) {}         // 网络错误处理器
 *          }
 *      }
 * }
 */
export default class Socket {
    
    /**
     * 初始化
     * 
     * @param {Object} setting 设置对象
     */
    constructor(setting) {

        // 设置对象
        this.setting = setting;

        // socket对象
        this.socket = null;

        // 是否在线指示器
        this.online = false;

        // 初始化socket，并连接服务器
        this.connect();
    }

    /**
     * 初始化socket，并设置默认事件
     * 
     * @param {String} url 连接的url地址
     */
    connect() {
        
        // --------------------------------------------------------
        // 初始化，并发起连接
        this.socket = io(this.setting.url);

        // --------------------------------------------------------
        // 连接成功，指示当前已在线
        this.socket.on('connect', ()=> {
            this.online = true;
        });

        // --------------------------------------------------------
        // 连接失败，记录错误，指示当前已离线
        this.socket.on('connect_error', (err)=> {
            this.online = false;
        });

        // --------------------------------------------------------
        // 连接超时，记录超时，指示当前已离线
        this.socket.on('connect_timeout', (timeout)=> {
            this.online = false;
        });

        // --------------------------------------------------------
        // 任意错误，记录错误
        this.socket.on('error', (err)=> {
            this.online = false;
        });

        // --------------------------------------------------------
        // 关闭连接，指示当前已离线
        this.socket.on('disconnect', (reason)=> {
            this.online = false;
        });

        // --------------------------------------------------------
        // 重新连接完成，指示当前已在线
        this.socket.on('reconnect', (attemptNumber)=> {
            this.online = true;
        });

        // --------------------------------------------------------
        // 再次连接失败，记录失败，指示当前已离线，
        this.socket.on('reconnect_error', (err)=> {
            this.online = false;
        });

        // // 试图重新连接
        // this.socket.on('reconnect_attempt', (attemptNumber)=> { });

        // // 重新连接中，
        // this.socket.on('reconnection', (attemptNumber)=> { });

        // // 重新连接失败
        // this.socket.on('reconnect_failed', ()=> { });
    }

    /**
     * 重新连接
     */
    reconnect() {
        this.connect();
    }

    /**
     * 发送socket消息
     * 
     * @param {String} name 发送的事件名
     * @param {Any} data 发送的数据
     */
    emit(name, data) {

        // 如果当前在线，则发送
        if (this.online) {
            this.socket.emit(name, data);
        } 
        
        // 否则，记录错误
        else {

        }
    }

    /**
     * 接收socket消息
     * 
     * @param {String} name 监听的事件名
     * @param {Function} callback 监听的回调方法
     */
    on(name, callback) {
        this.socket.on(name, callback);
    }
}
